package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"github.com/astaxie/beego/logs"
	"net"
)

//初始化日志 输出与日志文件和控制台
func init() {
	logs.SetLogger(logs.AdapterConsole)
	logs.SetLogger(logs.AdapterFile, `{"filename":"./service.log" ,"level":6,"maxlines":0,"maxsize":0,"daily":true,"maxdays":1}`)
}
func main() {
	listener, e := net.Listen("tcp", ":10086")
	if e != nil {
		logs.Info("listen err=%v", e)
	}
	logs.Info("now waiting listener ")
	for {
		conn, e := listener.Accept()
		logs.Info("receive conn  = ", conn.RemoteAddr().String())
		if e != nil {
			logs.Info("Accept err=%v", e)
		}
		go handleConn(conn)
	}

	//d:=[...]byte{197 ,47 ,249, 9 ,175, 140, 255, 108 ,177, 171, 58, 184 ,166, 106,
	//	15 ,11, 15, 235, 67, 232, 0 ,53 ,40, 83 ,125, 123, 26, 21 ,199, 35, 44 ,99}
	//getInfo(d[:], []byte("wealthypower2019"))

	//d := [...]byte{0, 0, 249, 9, 175, 140, 255, 108, 177, 171, 58, 184, 166, 106,
	//	15, 11, 15, 235, 67, 232, 0, 53, 40, 83, 125, 123, 26, 21, 0, 0, 0, 0}
	//logs.Info(d[:])
	//logs.Info(trim0(d[:]))
}

//处理连接请求
func handleConn(con net.Conn) {
	data := make([]byte, 1024*10)
	n, err := con.Read(data)
	if err != nil {
		logs.Info("read err=%v", err)
	}
	data = data[:n]
	logs.Info("密文=%v", data)
	getDataInfo(data, []byte("wealthypower2019"))
}

func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}

func AesEncrypt(origData, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	origData = PKCS7Padding(origData, blockSize)
	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
	crypted := make([]byte, len(origData))
	blockMode.CryptBlocks(crypted, origData)
	return crypted, nil
}

func AesDecrypt(crypted, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
	origData := make([]byte, len(crypted))
	blockMode.CryptBlocks(origData, crypted)
	origData = PKCS7UnPadding(origData)
	return origData, nil
}

func getDataInfo(data, key []byte) {
	origData, err := AesDecrypt(data, key)
	logs.Info("原文1=", origData)
	logs.Info("原文2=", trim0(origData))
	if err != nil {
		panic(err)
	}
	logs.Info("trim before=", string(origData))
	logs.Info("trim  after=", string(trim0(origData)))
}

//去掉前后的0
func trim0(r []byte) []byte {
	if len(r) == 0 {
		return r
	}
	for {
		if r[0] == 0 {
			r = r[1:]
		} else if r[len(r)-1] == 0 {
			r = r[0 : len(r)-1]
		} else {
			break
		}
	}
	return r
}
